import ComponentBase from "../../ComponentBase";
import { Logger } from "../../Logger";
import JhaoScrollViewItem from "./JhaoScrollViewItem";

const { ccclass, property, menu } = cc._decorator;

enum Axis {
    HORIZONTAL = 0, //水平
    VERTICAL = 1    //垂直
}

enum Direction {
    HEADER_TO_FOOTER = 0,
    FOOTER_TO_HEADER = 1,
}

/**item出现动画的枚举 */
export enum JhaoScrollViewItemAppear {
    NONE = 0,
    SCALE = 1,//从小变大
    FADE = 2,//渐变出现
}

@ccclass
@menu("JhaoScrollView/JhaoScrollViewLayout")
export default class JhaoScrollViewLayout extends ComponentBase {

    @property({ type: cc.Enum(Axis), displayName: "排列方向" })
    private startAxis: Axis = Axis.VERTICAL
    @property({ type: cc.Enum(Direction), displayName: "排列子节点的方向" })
    private direction: Direction = Direction.HEADER_TO_FOOTER
    @property({ displayName: "上边距" })
    private paddingTop: number = 0
    @property({ displayName: "下边距" })
    private paddingBottom: number = 0
    @property({ displayName: "左边距" })
    private paddingLeft: number = 0
    @property({ displayName: "右边距" })
    private paddingRight: number = 0
    @property({ displayName: "每组item个数", tooltip: "单行的列数 或 单列的行数" })
    private column: number = 1
    @property({ type: cc.Enum(JhaoScrollViewItemAppear), displayName: "item出现动画", tooltip: "SIDE 从两边出现\nSCALE 从小变大\nFADE 渐变出现" })
    private itemAppear: JhaoScrollViewItemAppear = JhaoScrollViewItemAppear.NONE;
    @property({ displayName: "初始化间隔", type: cc.Float })
    private initItemInteval: number = 0.005
    @property({ displayName: "子节点分层数量", type:cc.Integer })
    private layerNum: number = 2
    @property(cc.Component.EventHandler)
    private refreshItemEvents: cc.Component.EventHandler[] = [];

    private layerParent: Array<cc.Node> = []
    private _scrollView: cc.ScrollView = null
    private maxItemNum: number = 0
    private startIndex: number = 0
    private showNum: number = 0
    private layerItemList: Array<Array<cc.Node>> = [

    ]

    private dataList:Array<any> = []


    onLoad(): void {
        super.onLoad()
        let scrollViewEventHandler: cc.Component.EventHandler = new cc.Component.EventHandler();
        scrollViewEventHandler.target = this.node; // 这个 node 节点是你的事件处理代码组件所属的节点
        scrollViewEventHandler.component = "JhaoScrollViewLayout";// 这个是代码文件名
        scrollViewEventHandler.handler = "onJhaoScrollEvent";
        this.scrollView().scrollEvents.push(scrollViewEventHandler)
        // Logger.log("JhaoScrollViewLayout===onLoad=")
        this.defaultItem().name = "item0"
        for (let i = 0; i < this.layerNum; i++) {
            let layerParent: cc.Node = new cc.Node("layer" + i)
            layerParent.parent = this.node
            this.layerParent[i] = layerParent
            this.layerItemList[i] = []
            this.defaultItem().getChildByName("layer" + i).active = false
            this.layerItemList[i][0] = cc.instantiate(this.defaultItem().getChildByName("layer" + i))
            Logger.log("JhaoScrollViewLayout onload=", i, this.layerItemList)
            this.layerItemList[i][0].parent = layerParent
            this.layerItemList[i][0].active = true
        }
    }

    onEnable(): void {
        super.onEnable()
        // Logger.log("JhaoScrollViewLayout===onEnable=")
    }

    public scrollView(): cc.ScrollView {
        if (!this._scrollView) {
            this._scrollView = this.node.parent.parent.getComponent(cc.ScrollView)
        }
        return this._scrollView
    }

    public view(): cc.Node {
        return this.node.parent
    }

    private defaultItem(): cc.Node {
        return this.node.children[0]
    }

    private hideAll() {
        this.hideAllChildren(this.node)
        for (let i = 0; i < this.layerParent.length; i++) {
            this.hideAllChildren(this.layerParent[i])
        }
    }

    // 设置scrollview个数
    public async total(value: number, dataList:Array<any> =[]) {
        // Logger.log("total==", value, this.maxItemNum, this.node.children)
        this.dataList = dataList;
        if (value == 0) {
            this.maxItemNum = value
            this.showNum = value
            this.hideAll()
            return
        }
        let isInit: boolean = false
        if (this.maxItemNum != value) {
            let showNum: number = 0
            this.maxItemNum = value;
            this.scrollView().stopAutoScroll()    //停止滚先
            let row: number = value % this.column == 0 ? (value / this.column) : (Math.ceil(value / this.column))
            if (this.startAxis == Axis.HORIZONTAL) {    //水平
                if (this.direction == Direction.HEADER_TO_FOOTER) {
                    // this.node.setAnchorPoint(0, 0.5)
                } else {
                    this.node.setAnchorPoint(1, 0.5)
                }
                this.node.width = this.paddingLeft + this.paddingRight + this.defaultItem().width * (row)
                this.node.height = this.node.parent.height;
                showNum = Math.ceil(this.view().width / this.defaultItem().width) * this.column * 2;
            }
            else { //垂直
                if (this.direction == Direction.HEADER_TO_FOOTER) {
                    // this.scrollView().scrollToTop()
                    // this.node.setAnchorPoint(0.5, 1)
                } else {
                    // this.scrollView().scrollToBottom()
                    this.node.setAnchorPoint(0.5, 0)
                }
                this.node.width = this.node.parent.width;
                this.node.height = this.paddingTop + this.paddingBottom + this.defaultItem().height * (row)
                showNum = Math.ceil(this.view().height / this.defaultItem().height) * this.column * 2;
            }
            let nowOffest: cc.Vec2 = this.scrollView().getScrollOffset()
            if (this.startAxis == Axis.HORIZONTAL) {    //水平
                this.scrollView().scrollToOffset(cc.v2(nowOffest.x + 0.001, nowOffest.y), 0.001);
            } else {

                this.scrollView().scrollToOffset(cc.v2(nowOffest.x, nowOffest.y + 0.001), 0.001);
            }
            this.showNum = showNum
            showNum = Math.min(showNum, value)
            isInit = true
        }

        // Logger.log("total=222=", this.node.width, this.node.height, isInit, value, this.showNum)
        this.resetShowItem(isInit)
    }

    private resetShowItem(isInit: boolean) {
        this.unscheduleAllCallbacks()
        if (isInit) {
            this.hideAll()
        }
        let count: number = 0
        let max: number = this.startIndex + this.showNum
        max = Math.min(max, this.maxItemNum)
        // Logger.log("resetShowItem==", this.startIndex, max)
        if (max > 0) {
            for (let i = this.startIndex; i < max; i++) {
                // if (showMv && this.itemAppear != JhaoScrollViewItemAppear.NONE) {
                if (isInit && this.itemAppear != JhaoScrollViewItemAppear.NONE) {
                    this.scheduleOnce(() => {
                        this.initOneItem(count, i, isInit)
                        count++
                    }, this.initItemInteval * i)
                }
                else {
                    this.initOneItem(count, i, isInit)
                    count++
                }
            }
        }
    }

    private initOneItem(count: number, index: number, isInit: boolean) {
        // let tempItemNode: cc.Node = this.node.children[count]
        let tempItemNode: cc.Node = this.node.getChildByName("item" + count)
        // Logger.log("initOneItem==", tempItemNode,count)
        if (!tempItemNode) {
            tempItemNode = cc.instantiate(this.defaultItem())
            tempItemNode.parent = this.defaultItem().parent;
            tempItemNode.name = "item" + count
        }
        tempItemNode.active = true
        // this.hideAllChildren(tempItemNode)
        let tempItem: JhaoScrollViewItem = tempItemNode.getComponent(JhaoScrollViewItem) || tempItemNode.addComponent(JhaoScrollViewItem);
        tempItem.index = index;

        let tx: number = 0
        let ty: number = 0
        if (this.startAxis == Axis.HORIZONTAL) {    //水平
            if (this.direction == Direction.HEADER_TO_FOOTER) {
                tx = this.defaultItem().width / 2 + this.paddingLeft + this.defaultItem().width * Math.floor(index / this.column);
                ty = -this.node.height / 2 + this.defaultItem().height / 2 + this.paddingTop + this.defaultItem().height * (index % this.column)
            } else {
                tx = -this.defaultItem().width / 2 - this.paddingRight - this.defaultItem().width * Math.floor(index / this.column);
                ty = -this.node.height / 2 + this.defaultItem().height / 2 + this.paddingBottom + this.defaultItem().height * (index % this.column)
            }
        } else { //垂直
            if (this.direction == Direction.HEADER_TO_FOOTER) {
                tx = -this.node.width / 2 + this.defaultItem().width / 2 + this.paddingLeft + this.defaultItem().width * (index % this.column);
                ty = -this.defaultItem().height / 2 - this.paddingTop - this.defaultItem().height * Math.floor(index / this.column)
            } else {
                tx = -this.node.width / 2 + this.defaultItem().width / 2 + this.paddingLeft + this.defaultItem().width * (index % this.column);
                ty = this.defaultItem().height / 2 + this.paddingBottom + this.defaultItem().height * Math.floor(index / this.column)
            }
        }
        // Logger.log("tempItem==", count, tx, this.defaultItem().width, index, this.column)
        tempItem.node.setPosition(tx, ty)
        if (isInit) {
            tempItem.playShowAnim(this.itemAppear, count)
        }
        let layerNodeList: Array<cc.Node> = []
        for (let i = 0; i < this.layerItemList.length; i++) {
            let layerItem: cc.Node = this.layerItemList[i][count]
            if (!layerItem) {
                layerItem = cc.instantiate(this.layerItemList[i][0])
                layerItem.parent = this.layerParent[i]
                this.layerItemList[i][count] = layerItem
            }
            layerNodeList.push(layerItem)
            // if (i == 1) {
            //     let lbIndex: cc.Label = this.getChild(layerItem, "lbIndex", cc.Label)
            //     lbIndex.string = "" + tempItem.index
            // }
            layerItem.setPosition(tx, ty)
            layerItem.active = true
            this.layerParent[i].active = true
        }
        this.notifyRefreshItem(tempItem, layerNodeList)
    }
    /** 通知给定的node刷新数据 */
    private notifyRefreshItem(tempItem: JhaoScrollViewItem, layerNodeList: Array<cc.Node>) {
        cc.Component.EventHandler.emitEvents(this.refreshItemEvents, tempItem.node, layerNodeList, tempItem.index, this.dataList)
    }

    private onJhaoScrollEvent(scrollView: cc.ScrollView) {
        let index: number = this.calculateStartIndex()
        if (index != this.startIndex) {
            this.startIndex = index
            // Logger.log("onJhaoScrollEvent=", this.startIndex)
            this.resetShowItem(false)
        }
    }


    //计算开始Index
    private calculateStartIndex() {
        let index: number = 0
        let temp: number = 0
        if (this.startAxis == Axis.HORIZONTAL) {    //水平
            temp = Math.floor(Math.abs(this.node.x) / this.defaultItem().width)
            index = temp * this.column
            // Logger.log("calculateStartIndex1111", this.node.x,this.defaultItem().width, temp, index)
        }
        else { //垂直
            temp = Math.floor(Math.abs(this.node.y) / this.defaultItem().height)
            index = temp * this.column
        }
        // Logger.log("calculateStartIndex===end=", index, this.startIndex)
        return index
    }



    onDisable(): void {
        super.onDisable()
    }



}